# -*- coding: utf-8 -*-

from flask import Flask, request, jsonify
import numpy as np
import time
import requests
import argparse
import os
import json
import base64
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer

USER_NAME = ['lxc', 'gjf']
USER_PWD = {'lxc': 'abc@123', 'gjf': '123@abc'}
SECRET_KEY = 'abcdefghijklmn'
BARCODE_LIST = ["D88888888", "E33333333"]
INV_ORG_ID_LIST = ["200592", "200591"]


def generate_token(user_id, expiration=3600):
    print("--------- start generate token --------------")
    s = Serializer(SECRET_KEY, expires_in=expiration)
    start_time = int(time.time())
    expire_time = time.strftime("%Y-%m-%d-%H:%M:%S", time.localtime(start_time + expiration))
    token = s.dumps({"id": user_id}).decode("ascii")
    return token, expire_time


def check_param_legal(req_key: str, req_value: str, value_legal_set: list = None) -> (bool, str):
    print("--------- check param  {0} : {1} --------------".format(req_key, req_value))
    if not req_value:
        rsp_json = jsonify({"IsError": True,
                            "Message": "{0} does not exist".format(req_key),
                            "ErrorCode": "-2"})
        return False, rsp_json

    if value_legal_set and req_value not in value_legal_set:
        rsp_json = jsonify({"IsError": True,
                            "Message": "{0} is illegal".format(req_key),
                            "ErrorCode": "-2"})
        return False, rsp_json
    return True, None


def create_app():
    app = Flask(__name__,
                root_path=os.getcwd())

    @app.route('/SignIn', methods=['POST'])
    def login():
        print("--------- receive request --------------")
        if request.content_type.startswith("application/json"):
            try:
                json_data = request.json
                if not isinstance(json_data, dict):
                    return jsonify({"IsError": True,
                                    "Message": "Invalid json data",
                                    "ErrorCode": -6})
            except Exception as e:
                return jsonify({"IsError": True,
                                "Message": "Invalid json data",
                                "ErrorCode": -6})
            user_name = json_data.get("User")
            print("--------- User Name {} --------------".format(user_name))
            user_pwd = json_data.get("Pwd")
            print("--------- User Pwd {} --------------".format(user_pwd))
            if (user_name is None) or (user_name not in USER_NAME):
                print("--------- Invalid User Name --------------")
                return jsonify({"IsError": True,
                                "Message": "Invalid User Name",
                                "ErrorCode": -6})
            elif user_pwd != USER_PWD[user_name]:
                print("--------- Invalid User Pwd --------------")
                return jsonify({"IsError": True,
                                "Message": "User Name OR Password Error",
                                "ErrorCode": -7})
            else:
                print("--------- accept data success --------------")
                token, expire_time = generate_token(user_name)
                message = {"Expired": expire_time,
                           "Token": token,
                           "TokenType": "Bearer"}
                return jsonify({"Data": message,
                                "IsError": False,
                                "Message": "",
                                "ErrorCode": 0})
        else:
            return jsonify({"IsError": True,
                            "Message": "Invalid content type",
                            "ErrorCode": -5})

    @app.route('/Query', methods=['POST'])
    def query():
        print("--------- receive request --------------")
        if request.content_type.startswith("application/json"):
            try:
                token = request.headers.get("Authorization")
                s = Serializer(SECRET_KEY)
                user = s.loads(token.replace("Bearer ", ""))
            except Exception as e:
                return jsonify({"IsError": True,
                                "Message": "Invalid token",
                                "ErrorCode": -7})
            try:
                json_data = request.json
                if not isinstance(json_data, dict):
                    return jsonify({"IsError": True,
                                    "Message": "Invalid json data",
                                    "ErrorCode": -6})
            except Exception as e:
                return jsonify({"IsError": True,
                                "Message": "Invalid json data",
                                "ErrorCode": -6})
            bar_code = json_data.get("BARCODE")
            project_code = json_data.get("PROJECTCODE")
            logical_code = json_data.get("LOGICAL_CODE")
            inv_org_id = json_data.get("INVORGID")

            ok, rsp = check_param_legal("BARCODE", bar_code, BARCODE_LIST)
            if not ok:
                return rsp
            ok, rsp = check_param_legal("PROJECTCODE", project_code)
            if not ok:
                return rsp
            ok, rsp = check_param_legal("LOGICAL_CODE", logical_code)
            if not ok:
                return rsp
            ok, rsp = check_param_legal("INVORGID", inv_org_id, INV_ORG_ID_LIST)
            if not ok:
                return rsp

            message = [
                {"BARCODE": bar_code,
                 "MODEL_NAME": "BCD-176M",
                 "CUSTOMER_MODEL": "BCD-176M",
                 "CONSUME_COUNTRY": "国内",
                 "PROJECTCODE": project_code,
                 "INV_ORG_ID": inv_org_id,
                 "LOGICAL_CODE": logical_code
                 }
            ]
            return jsonify({"Data": message,
                            "IsError": False,
                            "Message": "",
                            "ErrorCode": 0})
        else:
            return jsonify({"IsError": True,
                            "Message": "Invalid content type",
                            "ErrorCode": -5})

    @app.route('/Upload', methods=['POST'])
    def upload():
        print("--------- receive request --------------")
        if request.content_type.startswith("application/json"):
            try:
                json_data = request.json
                if not isinstance(json_data, dict):
                    return jsonify({"IsError": True,
                                    "Message": "Invalid json data",
                                    "ErrorCode": -6})
            except Exception as e:
                return jsonify({"IsError": True,
                                "Message": "Invalid json data",
                                "ErrorCode": -6})
            bar_code = json_data.get("BARCODE")
            inv_org_id = json_data.get("INV_ORG_ID")
            device_code = json_data.get("DEVICE_CODE")

            ok, rsp = check_param_legal("BARCODE", bar_code, BARCODE_LIST)
            if not ok:
                return rsp
            ok, rsp = check_param_legal("INV_ORG_ID", inv_org_id, INV_ORG_ID_LIST)
            if not ok:
                return rsp
            ok, rsp = check_param_legal("DEVICE_CODE", device_code)
            if not ok:
                return rsp

            print(request.json)
            return jsonify({"Data": True,
                            "IsError": False,
                            "Message": "success",
                            "ErrorCode": 0,
                            "updated_data":
                                {"BARCODE": bar_code,
                                 "DATETIME_ACQUISITION": json_data.get("INV_ORG_ID"),
                                 "DEVICE_CODE": device_code,
                                 "INV_ORG_ID": inv_org_id,
                                 "TEST_STATUS": json_data.get("TEST_STATUS"),
                                 "WORKCENTER_CODE": json_data.get("WORKCENTER_CODE"),
                                 "detectionLine": json_data.get("detectionLine"),
                                 "totalErrCode": json_data.get("totalErrCode"),
                                 "totalSteps": json_data.get("totalSteps"),
                                 "totalTest_conditions": json_data.get("totalTest_conditions"),
                                 "user": json_data.get("user"),
                                 "detail": [
                                     {"Args": [
                                         {"comment": json_data.get("comment"),
                                         "result": json_data.get("result"),
                                         "test_conditions": json_data.get("test_conditions"),
                                         "value": json_data.get("value")}
                                         ]}
                                 ]
                                }
                            })
        else:
            return jsonify({"IsError": True,
                            "Message": "Invalid content type",
                            "ErrorCode": -5})

    @app.route('/infer', methods=['POST'])
    def ai_infer():
        print("--------- receive request --------------")
        if request.content_type.startswith("application/json"):
            try:
                json_data = request.json
                if not isinstance(json_data, dict):
                    return jsonify({"IsError": True,
                                    "Message": "Invalid json data",
                                    "ErrorCode": -6})
            except Exception as e:
                return jsonify({"IsError": True,
                                "Message": "Invalid json data",
                                "ErrorCode": -6})
            image_infos = json_data.get("Files", None)
            # print("--------- get files {}--------------".format(image_infos))
            for info in image_infos:
                file_name = info.get("FileName")
                print("--------- file_name {}--------------".format(file_name))

                image_content = info.get("ImageData")
                image_bytes = base64.b64decode(image_content)
                file_path = os.path.join("./tmp_imgs", file_name)
                if not os.path.exists(os.path.dirname(file_path)):
                    os.makedirs(os.path.dirname(file_path))
                print("--------- file path {}--------------".format(file_path))
                with open(file_path, 'wb') as f:
                    f.write(image_bytes)
            return jsonify({"IsError": False,
                            "Message": "receive success",
                            "ErrorCode": 0})
        else:
            return jsonify({"IsError": True,
                            "Message": "Invalid content type",
                            "ErrorCode": -5})

    return app


def main():
    parser = argparse.ArgumentParser(description="MES Demo")
    parser.add_argument("--host",
                        default="127.0.0.1")
    parser.add_argument("--port",
                        default=8888)

    args = parser.parse_args()
    app = create_app()
    app.run(host=args.host, port=args.port, threaded=False, debug=False)


if __name__ == "__main__":
    exit(main())
